﻿using System.Collections.Generic;

namespace Raven
{
    //these enums are used as return values from each search update method
    public enum PathSearch
    {
        target_found,
        target_not_found,
        search_incomplete
    };

    public class PathManager<T> where T : IPathPlanner
    {
        private int _numSearchCyclesPerUpdate;
        private LinkedList<T> _searchRequest;

        public PathManager(int numCyclesPerUpdate)
        {
            _numSearchCyclesPerUpdate = numCyclesPerUpdate;
            _searchRequest = new LinkedList<T>();
        }

        //every time this is called the total amount of search cycles available will
        //be shared out equally between all the active path requests. If a search
        //completes successfully or fails the method will notify the relevant bot
        public void UpdateSearches()
        {
            int NumCyclesRemaining = _numSearchCyclesPerUpdate;

            //iterate through the search requests until either all requests have been
            //fulfilled or there are no search cycles remaining for this update-step.
            LinkedListNode<T> curPath = _searchRequest.First;
            while (NumCyclesRemaining-- > 0 && curPath != null)
            {
                //make one search cycle of this path request
                PathSearch result = curPath.Value.CycleOnce();

                //if the search has terminated remove from the list
                if (result == PathSearch.target_found || result == PathSearch.target_not_found)
                {
                    //remove this path from the path list
                    _searchRequest.Remove(curPath);
                }
                curPath = curPath.Next;

                if (curPath == null)
                {
                    curPath = _searchRequest.First;
                }
            } //end while
        }

        //a path planner should call this method to register a search with the 
        //manager. (The method checks to ensure the path planner is only registered
        //once)
        public void Register(T pPathPlanner)
        {
            if (!_searchRequest.Contains(pPathPlanner))
            {
                _searchRequest.AddLast(pPathPlanner);
            }
        }

        public void UnRegister(T pPathPlanner)
        {
            _searchRequest.Remove(pPathPlanner);
        }

        //returns the amount of path requests currently active.
        public int GetNumActiveSearches()
        {
            return _searchRequest.Count;
        }
    }
}